package com.marc.eden;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.content.ContextCompat;
import android.view.SurfaceHolder;

import java.util.Arrays;

import static android.os.Looper.getMainLooper;

public class Camera {

    public CameraManager cameraManager;
    public CameraDevice cameraDevice;
    public CameraCaptureSession cameraCaptureSession;
    public String cameraID;
    public CaptureRequest.Builder previewBuilder;
    public CaptureRequest.Builder pictureBuilder;

    public HandlerThread handlerThread;
    public Handler openCameraHandler, previewHandler, captureHandler;

    public SurfaceHolder surfaceHolder;
    public ImageReader imageReader;

    public Camera(Activity activity, SurfaceHolder surfaceHolder, ImageReader imageReader) {
        Camera.this.surfaceHolder = surfaceHolder;
        Camera.this.imageReader = imageReader;
        System.out.println("start!");
        initCamera(activity);
    }

    public void initCamera(Activity activity) {
        handlerThread = new HandlerThread("Camera");
        handlerThread.start();
        previewHandler = new Handler(handlerThread.getLooper());
        captureHandler = new Handler(handlerThread.getLooper());
        openCameraHandler = new Handler(getMainLooper());
        cameraID = ""+ CameraCharacteristics.LENS_FACING_BACK;
//        cameraID = ""+ CameraCharacteristics.LENS_FACING_FRONT;
        cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        openCamera(activity);
    }

    public void openCamera(Activity activity) {
        try {
            if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            cameraManager.openCamera(cameraID, cameraDeviceStateCallback, openCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    public CameraDevice.StateCallback cameraDeviceStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice cameraDevice) {
            Camera.this.cameraDevice = cameraDevice;
            if (null == surfaceHolder) {
                return;
            }
            takePreview(surfaceHolder, imageReader);
        }

        @Override
        public void onDisconnected(CameraDevice cameraDevice) {
            destroyCamera();
        }

        @Override
        public void onError(CameraDevice cameraDevice, int i) {
            System.out.println("CameraDevice is onError!");
        }
    };

    public void destroyCamera() {
        cameraDevice.close();
        cameraDevice = null;
        handlerThread.quitSafely();
    }

    public void takePreview(SurfaceHolder surfaceHolder, ImageReader imageReader) {
        try {
            previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//            previewBuilder.set();
            previewBuilder.addTarget(surfaceHolder.getSurface());
            cameraDevice.createCaptureSession(Arrays.asList(surfaceHolder.getSurface(), imageReader.getSurface()),
                    cameraCaptureSessionStateCallback, previewHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    public void takePicture(ImageReader imageReader) {
        if (cameraDevice == null) {
            return;
        }
        try {
            pictureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            pictureBuilder.addTarget(imageReader.getSurface());
//            pictureBuilder.set();
            CaptureRequest captureRequest = pictureBuilder.build();
            cameraCaptureSession.capture(captureRequest, null, captureHandler);//
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    public CameraCaptureSession.StateCallback cameraCaptureSessionStateCallback =
            new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
            if (null == cameraDevice) {
                return;
            }
            Camera.this.cameraCaptureSession = cameraCaptureSession;
            try {
                Camera.this.cameraCaptureSession.setRepeatingRequest(previewBuilder.build(),
                        null, previewHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
            System.out.println("CameraCaptureSession is onConfigureFailed!");
        }
    };
}
